"""
钉钉OAuth2登录路由 - 对应Django的DDGetUrl和DDCallback
"""
import uuid
from fastapi import APIRouter, Depends, status
from fastapi.responses import RedirectResponse, JSONResponse
from sqlalchemy.orm import Session
from database import get_db, User
from config import settings
from tools.auth import create_access_token
from datetime import datetime

router = APIRouter(prefix="/api/dingtalk", tags=["钉钉登录"])


@router.get("/get-auth-url")
async def get_dingtalk_auth_url():
    """
    获取钉钉授权URL，用于前端跳转
    对应Django的DDGetUrl
    """
    # 生成随机状态码，防止CSRF攻击
    state = str(uuid.uuid4())
    
    # 构建钉钉授权URL（回调到前端）
    redirect_uri = "http://localhost:3000/dingtalk-login"
    dingtalk_appid = settings.DINGTALK_APP_KEY
    
    # 使用正确的钉钉OAuth2接口和参数
    url = f"https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid={dingtalk_appid}&response_type=code&scope=openid&redirect_uri={redirect_uri}&state={state}"
    
    return JSONResponse({"code": 200, "msg": "获取成功！", "url": url})


@router.get("/callback")
async def dingtalk_callback(
    code: str,
    db: Session = Depends(get_db)
):
    """
    钉钉授权回调接口，获取用户信息并完成登录/注册
    对应Django的DDCallback
    """
    if not code:
        return RedirectResponse(url="http://localhost:3000/login?error=钉钉授权失败", status_code=status.HTTP_302_FOUND)
    
    try:
        # 根据code获取用户accessToken
        token_url = "https://api.dingtalk.com/v1.0/oauth2/userAccessToken"
        data = {
            "clientId": settings.DINGTALK_APP_KEY,
            "clientSecret": settings.DINGTALK_APP_SECRET,
            "code": code,
            "grantType": "authorization_code"
        }
        
        import requests
        response = requests.post(token_url, json=data).json()
        print("钉钉返回：", response)
        
        if "accessToken" not in response:
            return RedirectResponse(url="http://localhost:3000/login?error=钉钉授权失败", status_code=status.HTTP_302_FOUND)
        
        access_token = response["accessToken"]
        
        # 根据accessToken获取用户信息
        user_info_url = "https://api.dingtalk.com/v1.0/contact/users/me"
        headers = {"x-acs-dingtalk-access-token": access_token}
        user_info = requests.get(user_info_url, headers=headers).json()
        print("钉钉用户信息：", user_info)
        
        if "openId" not in user_info:
            return RedirectResponse(url="http://localhost:3000/login?error=获取钉钉用户信息失败", status_code=status.HTTP_302_FOUND)
        
        uid = user_info["openId"]
        name = user_info.get('nick', f"钉钉用户{uid[-8:]}")
        phone = user_info.get('mobile')
        
        # 查询或创建用户
        # 使用 phone 作为唯一标识（如果提供了手机号）
        if phone:
            user = db.query(User).filter(User.phone == phone).first()
        else:
            # 如果没有手机号，使用钉钉openId创建用户名
            username = f"ding_{uid}"
            user = db.query(User).filter(User.username == username).first()
        
        if not user:
            # 创建新用户
            username = phone if phone else f"ding_{uid}"
            user = User(
                username=username,
                password_hash="",  # 第三方登录不需要密码
                nickname=name,
                phone=phone,
                status=1,
                created_at=datetime.now(),
                updated_at=datetime.now()
            )
            db.add(user)
            db.commit()
            db.refresh(user)
            print(f"创建新用户: {user.username}")
        
        # 生成JWT token
        jwt_token = create_access_token(data={"sub": str(user.id)})
        
        # 重定向到前端
        redirect_url = f"http://localhost:3000/dingtalk-login?access_token={jwt_token}&user_id={user.id}&username={user.username}"
        return RedirectResponse(url=redirect_url, status_code=status.HTTP_302_FOUND)
        
    except Exception as e:
        print(f"钉钉回调处理失败: {e}")
        import traceback
        traceback.print_exc()
        return RedirectResponse(url="http://localhost:3000/login?error=服务器错误", status_code=status.HTTP_302_FOUND)